package com.suray.wcs.service.plc;

import com.suray.basic.wcs.path.enums.NodeStatus;
import com.suray.basic.wcs.path.enums.NodeType;
import com.suray.basic.wcs.plc.core.Plc;
import com.suray.basic.wcs.plc.enums.CargoState;
import com.suray.basic.wcs.plc.oper.PlcOper;
import com.suray.basic.wcs.plc.oper.impl.PlcOperImpl;
import com.suray.basic.wcs.plc.pojo.oper.StationOper;
import com.suray.basic.wcs.plc.utils.PlcUnit;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.wcs.service.enums.DetailProcess;
import com.suray.wcs.service.enums.PrecessStatus;
import com.suray.wcs.service.execption.PlcExecuteException;
import com.suray.wcs.service.system.entity.TaskDB;
import com.suray.wcs.service.system.entity.TaskDetailDB;
import com.suray.wcs.service.system.service.impl.NodeDBServiceImpl;
import com.suray.wcs.service.system.service.impl.TaskDetailServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * 输送线调用的集合类
 */
public class ConveyEvent {
    private static Logger log = LoggerFactory.getLogger(ConveyEvent.class);

    private static NodeDBServiceImpl nodedbServiceImpl = SpringContextHolder.getBean(NodeDBServiceImpl.class);
    private static TaskDetailServiceImpl taskDetailService = SpringContextHolder.getBean(TaskDetailServiceImpl.class);


    /**
     * 调用输送线运行
     *
     * @param startStation 输送线操作对象
     * @param taskDB     任务
     * @return
     * @throws PlcExecuteException
     */
    public static void conveyRun(TaskDB taskDB, Integer plcId, StationOper startStation, StationOper endStation,
                                 TaskDetailDB stationTask) throws PlcExecuteException, IOException {
        PlcOper plcOper = PlcOperImpl.getPlcOper(startStation.getPlc());
        try {
            log.info("输送线运行命令发送：起点：" + startStation.getDeviceName() + ",终点：" + endStation.getDeviceName());
            int startNo = startStation.getDeviceNo();
            int endNo = endStation.getDeviceNo();
            log.info("输送线运行命令发送：起点设备号：" + startNo + ",终点设备号：" + endNo);
            TaskDetailDB taskDetailDB = null;
            if (stationTask != null) {
                taskDetailDB = taskDetailService.getTaskDetail(plcId, DetailProcess.STATION_INSTRUCTION,
                        stationTask.getUuid(), startStation.getDeviceName(), endStation.getDeviceName(),
                        PrecessStatus.CONDUCT, null, null);
            }
            plcOper.conveyorTask(plcId, startStation, endStation);
            if (taskDetailDB != null) {
                taskDetailService.updateTaskDetailCompleteTime(taskDetailDB);
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.info("输送线指令下发通信异常" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            log.info("输送线指令下发出现异常" + e.getMessage());
        }

        checkConveyTaskStatus(startStation, plcId, taskDB);
        //任务完成验证
        checkConveyTaskFinish(endStation, plcId, taskDB);
    }

    private static void checkConveyTaskStatus(StationOper stationOper, Integer plcId, TaskDB taskDB) throws IOException {
        log.info("等待输送线" + stationOper.getDeviceName() + "的" + plcId + "号任务离开起始工位");
        while (plcId.equals(stationOper.getPalletNo()) || stationOper.isPalletExist() || stationOper.isRunIng()) {
            if (taskDB != null) {
                Plc.checkPLCInterrupt(taskDB.getTaskId().toString(), "conveyRun1");
            }
            log.info("等待输送线" + stationOper.getDeviceName() + "的" + plcId + "号任务离开起始工位");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if (PlcUnit.getAutomaticLifterOper(stationOper.getCoord()) != null) {
            nodedbServiceImpl.updateNodeDBStatus(stationOper.getCoord(), NodeStatus.N.toString());
            PlcUnit.writeTwoDirectionRgvCargoState(stationOper.getCoord(), CargoState.No_CARGO);
        } else if (NodeType.CONNECTION.equals(nodedbServiceImpl.getNodeDB(stationOper.getCoord()).getGridType())) {
            nodedbServiceImpl.updateNodeDBStatus(stationOper.getCoord(), NodeStatus.N.toString());
        }
        log.info("输送线" + stationOper.getDeviceName() + "的" + plcId + "号任务离开起始工位，更新货位状态为无货");
    }

    private static void checkConveyTaskFinish(StationOper stationOper, Integer plcId, TaskDB taskDB) {
        log.info("等待输送线" + stationOper.getDeviceName() + "的" + plcId + "号任务完成");
        while (!plcId.equals(stationOper.getPalletNo()) || !stationOper.isPalletExist() || stationOper.isRunIng()) {
            if (taskDB != null) {
                Plc.checkPLCInterrupt(taskDB.getTaskId().toString(), "conveyRun1");
            }
            log.warn(stationOper.getDeviceName() + "输送线的任务" + taskDB.getPlcId() + "未结束！");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        log.info("输送线" + stationOper.getDeviceName() + "的" + plcId + "号任务完成");
    }
}
